Multiplexed Server Design এবং উদাহরণ

Computer Programming - ইউনিক্স সকেট (Unix Socket) Socket I/O Multiplexing (Socket I/O Multiplexing) |
253
253

Multiplexed Server Design

Multiplexed Server Design হল একটি নেটওয়ার্ক সার্ভারের ডিজাইন প্যাটার্ন যেখানে একাধিক ক্লায়েন্টের সাথে একযোগে যোগাযোগ পরিচালনা করা হয়, সাধারণত একটি একক থ্রেড বা প্রসেসের মাধ্যমে। এটি সিস্টেমের স্কেলেবিলিটি এবং পারফরম্যান্স বৃদ্ধির জন্য ব্যবহৃত হয়, কারণ এতে একাধিক ক্লায়েন্টের জন্য আলাদা থ্রেড তৈরি করার প্রয়োজন হয় না। এর বদলে, সিস্টেম একযোগে একাধিক সংযোগ পরিচালনা করতে select(), poll(), বা epoll() ব্যবহার করে, যা সকেট I/O এর জন্য অপেক্ষা না করে একাধিক কানেকশনের সাথে কাজ করতে সাহায্য করে।

এই ডিজাইনটি সাধারণত একটি ইভেন্ট-ড্রিভেন আর্কিটেকচার, যেখানে সার্ভার শুধুমাত্র সকেট I/O এর জন্য অপেক্ষা করে এবং যেকোনো সকেট যদি প্রস্তুত থাকে (যেমন ডেটা আসা), তখন সে সকেটটির সাথে ইন্টারঅ্যাক্ট করে।


Multiplexed Server Design এর উপকারিতা

  1. কম রিসোর্স খরচ: একাধিক থ্রেড বা প্রসেস না তৈরি করার কারণে সিস্টেমের রিসোর্স ব্যবহার কম হয়, বিশেষ করে মেমরি এবং প্রসেসিং ক্ষমতা।
  2. উচ্চ স্কেলেবিলিটি: একযোগে হাজার হাজার ক্লায়েন্টের সাথে কাজ করা যায়, কারণ এটি নন-ব্লকিং I/O এবং ইভেন্ট ড্রিভেন আর্কিটেকচার ব্যবহার করে।
  3. সহজ সিঙ্ক্রোনাইজেশন: থ্রেড বা প্রসেস সিঙ্ক্রোনাইজেশন প্রয়োজন নেই, কারণ একক থ্রেডে সমস্ত কাজ করা হয়।

Multiplexed Server Design এর উদাহরণ

এখানে একটি Multiplexed TCP Server এর উদাহরণ দেখানো হলো যা একাধিক ক্লায়েন্টের সাথে নন-ব্লকিং I/O এবং select() ব্যবহারের মাধ্যমে কাজ করে। এই সার্ভার একযোগে অনেক ক্লায়েন্টের সাথে সংযোগ স্থাপন এবং ডেটা গ্রহণ করে, তবে একাধিক থ্রেড বা প্রসেস ব্যবহৃত হয় না।

উদাহরণ: Multiplexed TCP Server Using select()

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/select.h>
#include <arpa/inet.h>

#define PORT 65432
#define MAX_CLIENTS 10

int main() {
    int server_socket, client_socket, max_sd;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_len = sizeof(client_addr);
    char buffer[1024];
    fd_set readfds;

    // সার্ভার সকেট তৈরি
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket == -1) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    // সার্ভারের IP এবং পোর্ট সেট করা
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(PORT);

    // সার্ভার সকেটে বাইন্ড করা
    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("Bind failed");
        exit(EXIT_FAILURE);
    }

    // লিসেনিং শুরু করা
    if (listen(server_socket, 5) == -1) {
        perror("Listen failed");
        exit(EXIT_FAILURE);
    }

    printf("Server is listening on port %d...\n", PORT);

    // `select()` ব্যবহারের জন্য সকেট সেটআপ
    FD_ZERO(&readfds);
    FD_SET(server_socket, &readfds);
    max_sd = server_socket;

    // ক্লায়েন্টের সংযোগের জন্য অপেক্ষা
    while (1) {
        fd_set tempfds = readfds;
        int activity = select(max_sd + 1, &tempfds, NULL, NULL, NULL);

        if (activity == -1) {
            perror("select error");
            exit(EXIT_FAILURE);
        }

        // নতুন সংযোগ পাওয়া গেলে
        if (FD_ISSET(server_socket, &tempfds)) {
            client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_len);
            if (client_socket == -1) {
                perror("Accept failed");
                continue;
            }
            printf("New client connected\n");
            FD_SET(client_socket, &readfds);
            if (client_socket > max_sd) max_sd = client_socket;
        }

        // সকেট থেকে ডেটা পড়া
        for (int i = 0; i <= max_sd; i++) {
            if (FD_ISSET(i, &tempfds)) {
                int valread = read(i, buffer, sizeof(buffer));
                if (valread == 0) {
                    printf("Client disconnected\n");
                    close(i);
                    FD_CLR(i, &readfds);
                } else {
                    printf("Received from client: %s\n", buffer);
                    send(i, "Message received", 16, 0);
                }
            }
        }
    }

    close(server_socket);
    return 0;
}

ব্যাখ্যা:

  1. সার্ভার সকেট তৈরি: socket() ফাংশন দিয়ে একটি TCP সকেট তৈরি করা হয়েছে এবং bind() এর মাধ্যমে এটি একটি নির্দিষ্ট পোর্টে বাইন্ড করা হয়েছে।
  2. লিসেনিং এবং select() ব্যবহারের জন্য সেটআপ: সার্ভার select() ফাংশন ব্যবহার করে সকেটের উপর নজর রাখছে, এবং যখন কোনো নতুন ক্লায়েন্ট সংযোগ স্থাপন করবে, তখন সেই সকেটকে readfds সেটে যোগ করা হবে।
  3. নতুন ক্লায়েন্টের সংযোগ গ্রহণ: যদি একটি নতুন ক্লায়েন্ট সংযোগ স্থাপন করে, তাহলে accept() ফাংশন ব্যবহার করে সংযোগ গ্রহণ করা হয়।
  4. ডেটা প্রাপ্তি এবং পাঠানো: ক্লায়েন্ট থেকে ডেটা পাঠানো হলে তা গ্রহণ করা হয় এবং একটি উত্তর পাঠানো হয়।
  5. একাধিক ক্লায়েন্ট পরিচালনা: select() ফাংশনটি একযোগে একাধিক ক্লায়েন্টের সংযোগ এবং ডেটা প্রক্রিয়া করতে সক্ষম।

Multiplexed Server Design এর উপকারিতা:

  1. কম রিসোর্স ব্যবহার: একক থ্রেড বা প্রসেসে একাধিক ক্লায়েন্টের সাথে কাজ করার ফলে রিসোর্সের ব্যবহার কম হয় এবং এটি উচ্চ কার্যকারিতা নিশ্চিত করে।
  2. স্কেলেবিলিটি: সহজেই আরও ক্লায়েন্ট সংযুক্ত করা সম্ভব, কারণ প্রতি ক্লায়েন্টের জন্য নতুন থ্রেড বা প্রসেস তৈরি করার প্রয়োজন নেই।
  3. প্রযুক্তিগত জটিলতা কম: একক থ্রেডে সমস্ত কাজ করতে গেলে সিঙ্ক্রোনাইজেশন সমস্যা কমে যায় এবং কোডের জটিলতা কম হয়।

উপসংহার

Multiplexed Server Design হল একটি শক্তিশালী এবং স্কেলেবল নেটওয়ার্ক আর্কিটেকচার প্যাটার্ন, যেখানে একাধিক ক্লায়েন্টকে একযোগভাবে পরিচালনা করা যায়। select(), poll(), বা epoll() ফাংশন ব্যবহার করে এই ধরনের সার্ভার ডিজাইন তৈরি করা সম্ভব, যা কম রিসোর্সে অধিক কার্যকারিতা প্রদান করে এবং সিস্টেমের স্কেলেবিলিটি বাড়ায়।

common.content_added_by
টপ রেটেড অ্যাপ

স্যাট অ্যাকাডেমী অ্যাপ

আমাদের অল-ইন-ওয়ান মোবাইল অ্যাপের মাধ্যমে সীমাহীন শেখার সুযোগ উপভোগ করুন।

ভিডিও
লাইভ ক্লাস
এক্সাম
ডাউনলোড করুন
Promotion